/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simplemetrosystem.view.table;

import java.awt.Component;
import javax.swing.DefaultCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import simplemetrosystem.control.EditCommandManager;
import simplemetrosystem.control.ElementManager;
import simplemetrosystem.model.Element.MetroEdge;
import simplemetrosystem.model.Element.MetroLine;
import simplemetrosystem.model.Element.MetroStation;
import simplemetrosystem.model.charlanguage.NameMap;
import simplemetrosystem.view.InformationPane;
import simplemetrosystem.view.table.Exceptions.InformationPanelException;

/**
 *
 * @author Eric Qian
 */
public class StationTable extends JTable {

    public StationTable(InformationPane infPane, MetroStation station) {
        super();
        this.infPane = infPane;
        this.station = station;
        stationModel = new StationModel(infPane, station);
        this.setModel(stationModel);
        this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        setRowSelectionAllowed(false);
        getTableHeader().setReorderingAllowed(false);
        getTableHeader().setResizingAllowed(false);

        setCell();

        this.setRowHeight(ROW_HEI);
    }

    private void setCell() {
        TableColumn valColumn = columnModel.getColumn(StationModel.COL_VAL);
        valColumn.setCellEditor(new StationValCellEditor(infPane, this));
    }

    public MetroStation getStation() {
        return station;
    }
    private InformationPane infPane;
    private MetroStation station;
    private StationModel stationModel;
    private static final int ROW_HEI = 20;
}

class StationModel extends AbstractTableModel {

    public StationModel(InformationPane infPane, MetroStation station) {
        super();
        this.infPane = infPane;
        this.station = station;
        elementManager = ElementManager.getInstance();
        nameMap = NameMap.getInstance();
        initArray();
    }

    private void initArray() {
        rowLineSize = station.getLinesSize();
        rowEdgeSize = station.getEdgesSize();

        rowCount = 8 + rowLineSize * 2 + rowEdgeSize * 2;
        int row = 0;

        rowNames = new String[rowCount];
        rowElems = new String[rowCount];

        rowNames[row] = nameMap.getName("English Name");
        rowElems[row++] = station.getName();

        rowNames[row] = nameMap.getName("Chinese Name");
        rowElems[row++] = station.getChineseName();

        rowNames[row] = nameMap.getName("Logic X");
        rowElems[row++] = "" + station.getLogX();

        rowNames[row] = nameMap.getName("Logic Y");
        rowElems[row++] = "" + station.getLogY();

        rowNames[row] = nameMap.getName("Natual X");
        rowElems[row++] = "" + station.getNatX();

        rowNames[row] = nameMap.getName("Natual X");
        rowElems[row++] = "" + station.getNatX();

        rowNames[row] = nameMap.getName("Lines Number");
        rowElems[row++] = "" + rowLineSize;

        rowLineStart = row;
        for (int i = 0; i < station.getLinesSize(); i++) {
            if (i == 0) {
                rowNames[row] = nameMap.getName("Lines(English)");
            }
            rowElems[row++] = station.getLineAt(i).getName();
        }

        for (int i = 0; i < station.getLinesSize(); i++) {
            if (i == 0) {
                rowNames[row] = nameMap.getName("Lines(Chinese)");
            }
            rowElems[row++] = station.getLineAt(i).getChineseName();
        }

        rowNames[row] = nameMap.getName("Edges Number");
        rowElems[row++] = "" + rowEdgeSize;

        rowEdgeStart = row;
        for (int i = 0; i < station.getEdgesSize(); i++) {
            if (i == 0) {
                rowNames[row] = nameMap.getName("Edges(English)");
            }
            rowElems[row++] = station.getEdgeAt(i).getName();
        }
        for (int i = 0; i < station.getEdgesSize(); i++) {
            if (i == 0) {
                rowNames[row] = nameMap.getName("Edges(Chinese)");
            }
            rowElems[row++] = station.getEdgeAt(i).getChineseName();
        }
    }

    public int getRowCount() {
        return rowCount;
    }

    @Override
    public String getColumnName(int column) {
        if (column == COL_PRO) {
            return nameMap.getName("Property");
        } else if (column == COL_VAL) {
            return nameMap.getName("Value");
        } else {
            return "???";
        }
    }

    public int getColumnCount() {
        return COL_COUNT;
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if ((rowIndex == ROW_NAM || rowIndex == ROW_CNAM ||
                (rowIndex >= rowLineStart && rowIndex != rowEdgeStart - 1)) && columnIndex == COL_VAL) {
            return true;
        }
        return false;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        editCommandManager = EditCommandManager.getInstance();
        if (rowIndex == ROW_NAM) {
            editCommandManager.EditStation(station, (String) aValue,
                    station.getChineseName(), station.getLogX(),
                    station.getLogY(), station.getNatX(), station.getNatY());
        } else if (rowIndex == ROW_CNAM) {
            editCommandManager.EditStation(station, station.getName(),
                    (String) aValue, station.getLogX(),
                    station.getLogY(), station.getNatX(), station.getNatY());
        }
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex == COL_PRO) {
            return rowNames[rowIndex];
        } else if (columnIndex == COL_VAL) {
            return rowElems[rowIndex];
        } else {
            return "???";
        }
    }

    /**
     * 
     * @return
     */
    public int getRowLineStart() {
        return rowLineStart;
    }

    /**
     * 
     * @return
     */
    public int getRowLineSize() {
        return rowLineSize;
    }

    /**
     * 
     * @return
     */
    public int getRowEdgeStart() {
        return rowEdgeStart;
    }

    /**
     * 
     * @return
     */
    public int getRowEdgeSize() {
        return rowEdgeSize;
    }

    /**
     * 
     * @param i
     * @return
     */
    public MetroLine getLineAt(int i) {
        return station.getLineAt(i);
    }

    /**
     * 
     * @param i
     * @return
     */
    public MetroEdge getEdgeAt(int i) {
        return station.getEdgeAt(i);
    }
    private InformationPane infPane;
    private NameMap nameMap;
    private MetroStation station;
    private ElementManager elementManager;
    private EditCommandManager editCommandManager;
    private String[] rowNames;
    private String[] rowElems;
    private int rowCount;
    private int rowLineStart;
    private int rowLineSize;
    private int rowEdgeStart;
    private int rowEdgeSize;
    public static final int COL_COUNT = 2;
    public static final int COL_PRO = 0;
    public static final int COL_VAL = 1;
    public static final int ROW_NAM = 0;
    public static final int ROW_CNAM = 1;
}

class StationValCellEditor extends DefaultCellEditor {

    public StationValCellEditor(InformationPane infPane, StationTable table) {
        super(new JTextField());
        this.infPane = infPane;
        this.table = table;
        this.model = (StationModel) table.getModel();
    }

    @Override
    public Object getCellEditorValue() {
        return super.getCellEditorValue();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        try {
            StationModel aModel = (StationModel) table.getModel();
            if (row >= model.getRowLineStart() && row < model.getRowEdgeStart()) {
                infPane.setFocus(InformationPane.LINE,
                        aModel.getLineAt((row - model.getRowLineStart()) % model.getRowLineSize()));
                return null;
            } else if (row >= model.getRowEdgeStart()) {
                infPane.setFocus(InformationPane.EDGE,
                        aModel.getEdgeAt((row - model.getRowEdgeStart()) % model.getRowEdgeSize()));
                return null;
            } else {
                return super.getTableCellEditorComponent(table, value, isSelected, row, column);
            }
        } catch (InformationPanelException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    private InformationPane infPane;
    private StationTable table;
    private StationModel model;
}
